#include "CCommon.h"

#include <QDebug>
#include <QString>
#include <string.h>
#include <iostream>

#include "../CGlobal.h"
#include "../COperationCodes.h"
#include "../CCoreException.h"
#include "../CVMDataTypes.h"
#include "../data/CFunction.h"

void push(CFrame& frame)
{
    int& pntr = frame.pointer();

    if (frame.codeSize() - pntr < (int)sizeof(int))
        throw CCoreException(CCoreException::VM_EXCEPTION_UNEXPECTED_END_OF_INPUT, "<operations.common.push>");

    int sz = *(int*)(frame.code() + pntr);
    pntr += sizeof(int);

    if (frame.codeSize() - pntr < sz)
        throw CCoreException(CCoreException::VM_EXCEPTION_UNEXPECTED_END_OF_INPUT, "<operations.common.push>");

    char* vl = new char[sz];
    memcpy(vl, frame.code() + pntr, sz);
    pntr += sz;
    frame.pushOperand(vl);
}

void pop(CFrame& frame)
{
    if (frame.operandCount() < 1)
        throw CCoreException(CCoreException::VM_EXCEPTION_INSUFFICIENT_OPERANDS, "<operations.common.pop>");
    delete[] frame.popOperand();
}

void bind(CFrame& frame)
{
    if (frame.operandCount() < 2)
        throw CCoreException(CCoreException::VM_EXCEPTION_INSUFFICIENT_OPERANDS, "<operations.common.bind>");

    QString nm = QString::fromUtf8(frame.peekOperand());
    delete[] frame.popOperand();

    if (frame.variables().contains(nm)) delete[] frame.variables()[nm];

    frame.variables()[nm] = copy(frame.peekOperand());
}

void getVar(CFrame& frame)
{
    if (frame.operandCount() < 1)
        throw CCoreException(CCoreException::VM_EXCEPTION_INSUFFICIENT_OPERANDS, "<operations.common.getVar>");

    QString nm = QString::fromUtf8(frame.peekOperand());
    delete[] frame.popOperand();

    char* vl;
    if (frame.variables().contains(nm)) vl = frame.variables()[nm];
    else if (CGlobal::globalVariables.contains(nm)) vl = CGlobal::globalVariables[nm];
    else
    {
        vl = new char;
        *vl = (char)CVMDataTypes::NULL_;
    }

    frame.pushOperand(copy(vl));
}

